package aupdg.presentation.adapter.impl;

import aupdg.data.DirectedGraphCustom;
import aupdg.presentation.adapter.LdgToDirectedGraph;
import aupdg.data.model.Edge;
import aupdg.data.model.Ldg;
import aupdg.data.model.Node;
import aupdg.data.model.impl.AuControlDependenceEdge;
import aupdg.data.model.impl.AuDataDependenceEdge;
import edu.uci.ics.jung.graph.util.EdgeType;
import java.util.List;

/**
 * Implements the contract LdgToDirectedGraph for generating a directed graph
 * which represents an LDG object.
 *
 * @author AA and CJ
 */
public class LdgToDirectedGraphImpl implements LdgToDirectedGraph {

    @Override
    public DirectedGraphCustom<Node, Edge> convert(Ldg ldg) {
        //DirectedGraph<Node, Edge> graph = new DirectedSparseMultigraph<Node, Edge>();
        DirectedGraphCustom<Node, Edge> graph = new DirectedGraphCustom<>();

        // We start with the nodes:
        Node startNode = ldg.getEntryNode();
        graph.addVertex(startNode);

        for (int i = 0; i < ldg.getNodeIds().size(); i++) {
            Node sourceNode = ldg.getNode(i);
            aupdg.data.model.Node ldgNode = ldg.getNode(i);
            graph.addVertex(sourceNode, ldgNode);
            List<Edge> adjEdges = ldg.getAdjacentEdgesFromNode(sourceNode);
            for (int j = 0; j < adjEdges.size(); j++) {
                Edge edge = adjEdges.get(j);
                if (edge instanceof AuControlDependenceEdge) {
                    graph.addEdge(edge, sourceNode,
                            edge.getTarget(), EdgeType.DIRECTED);
                } else if (edge instanceof AuDataDependenceEdge) {
                    graph.addEdge((AuDataDependenceEdge) edge, sourceNode,
                            edge.getTarget(), EdgeType.DIRECTED, Boolean.TRUE);
                }
            }
        }
        return graph;
    }
}
